<?php
/**
 * Created by PhpStorm.
 * User: yiyu
 * Email: smalleasyu@gmail.com
 * Date: 2020-01-18 22:43:44
 * Desc:
 */

namespace app\base\model\user;

use think\Model;
use MessageMap\Rabbit\MsgProducer;
use app\core\cache\{RedisCache, RedisKeys};
use think\Request;
use think\helper\Str;
use app\core\log\Log4dd;

class User extends Model
{
    protected $autoWriteTimestamp = false;
    protected $table = 'xy_user.xy_user';

    const ACCOUNT_STATUS_FREEZE = 2;
    const ACCOUNT_STATUS_LOGOUT = 3;

    const ACCOUNT_TYPE_ROBOT = 9;

    const REVIEW_USER_ID = 100197;

    const TEST_USER_ARR = [
        'ceshizhanghao' => [
            'password' => 'ceshizhanghao',
            'user_id' => 100197,
        ],
        'ceshizhanghao1' => [
            'password' => 'ceshizhanghao1',
            'user_id' => 100057,
        ]
    ];

    public function __construct($data = [])
    {
        parent::__construct($data);
        RedisCache::selectDB(config('redis_db_index.user'));
    }

    public static function miniProgramRegisterNewUser($data)
    {
        Log4dd::info('用户注册(第1步)', func_get_args());

        //$data['username'] = $data['register_mobile'];

        $data['register_client_id'] = CLIENT_ID;
        $data['register_time'] = date('Y-m-d H:i:s');
        $data['register_ip'] = Request::instance()->ip();
        $data['register_version'] = CLIENT_VERSION;

        $data['refer_code'] = self::genReferCode();

        Log4dd::info('用户注册(第2步)', $data);
        $user = self::create($data);

        if ($user->user_id) {
            $userInfo = $user->toArray();
            if (isset($data['username'])) {
                RedisCache::zAdd(RedisKeys::getUserListKey(), $user->user_id, $data['username']);
            }
            //self::sendRegisterMsg($user, $data);
            return $userInfo;
        }

        return false;

    }


    /**
     * 发送注册消息
     * @param $user
     * @param $data
     */
    private static function sendRegisterMsg($user, $data)
    {
        MsgProducer::sendRegisterMsg($user->user_id, [
            'channel' => $data['channel'],
            'register_mobile' => $data['register_mobile'],
            'refer_user_id' => $data['refer_user_id'] ?? '',
        ]);
    }

    public static function genReferCode()
    {
        do {
            $refer_code = random(6, 'upper');
            $vo = self::field('user_id')->where('refer_code', $refer_code)->find();
        } while ($vo);

        return $refer_code;
    }


    /**
     * 根据用户名获取用户ID
     * @param type $username
     * @return type
     */
    public static function getUserIdByUsername($username)
    {
        $listKey = RedisKeys::getUserListKey();
        $user_id = RedisCache::zScore($listKey, $username);
        if (!$user_id) {
            $user_id = User::where('username', $username)->value('user_id');
            if ($user_id) {
                RedisCache::zAdd($listKey, $user_id, $username);
            }
        }
        return $user_id;
    }

    public static function getUserIdByMobile($mobile)
    {
        $listKey = RedisKeys::getUserListKey();
        $user_id = RedisCache::zScore($listKey, $mobile);
        if (!$user_id) {
            $user_id = User::where('register_mobile', $mobile)->value('user_id');
            if ($user_id) {
                RedisCache::zAdd($listKey, $user_id, $mobile);
            }
        }
        return $user_id;
    }

    public static function getReferCodeByUserId($user_id)
    {
        $refer_code = self::where('user_id', $user_id)->value('refer_code');
        return $refer_code;
    }

    /**
     * 根据邀请码获取用户ID
     * @param string $referCode
     * @return int
     */
    public static function getUserIdByReferCode($referCode)
    {
        $user_id = self::where('refer_code', $referCode)->value('user_id');
        return $user_id;
    }

    /**
     * 根据 referCode 获取用户信息
     *
     * @param $referCode
     * @return array|false|\PDOStatement|string|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getUserInfoByReferCode($referCode)
    {
        return self::where('refer_code', $referCode)->find();
    }

    /**
     * 根据ID获取用户信息
     * @param int $user_id
     * @param array $fields
     * @return array $user
     */
    public static function getUserInfoById($user_id, $fields = [])
    {
        $key = RedisKeys::getUserIdKey($user_id);
        if (!RedisCache::hexists($key, 'user_id')) {
            $row = self::get($user_id);
            if ($row) {
                $row = $row->toArray();
                RedisCache::hMset($key, $row);
            } else {
                return [];
            }
        }

        if (!empty($fields)) {
            return RedisCache::hMGet($key, $fields);
        } else {
            return RedisCache::hGetAll($key);
        }
    }

    public static function getUserFieldById($user_id, $field)
    {
        $key = RedisKeys::getUserIdKey($user_id);
        if (!RedisCache::hexists($key, $field)) {
            $row = self::getUserInfoById($user_id, [$field]);
            return $row[$field] ?? '';
        } else {
            return RedisCache::hget($key, $field);
        }
    }

    public static function getNickNameById($user_id)
    {
        $key = RedisKeys::getUserIdKey($user_id);
        if (!RedisCache::hexists($key, 'nick_name')) {
            $row = self::getUserInfoById($user_id, ['nick_name']);
            return $row['nick_name'] ?? '圈友';
        } else {
            return RedisCache::hget($key, 'nick_name');
        }
    }

    public static function setUserInfoById($user_id, $data)
    {
        $key = RedisKeys::getUserIdKey($user_id);
        //$info = self::getUserInfoById($user_id);
        $listKey = RedisKeys::getUserListKey();
        //修改缓存
        foreach ($data as $filed => $value) {
            RedisCache::hSet($key, $filed, $value);
        }
        if (isset($data['username']) || isset($data['register_mobile'])) {
            //RedisCache::zDelete($listKey, $info['username']);
            RedisCache::zAdd($listKey, $user_id, $data['username']);
        }
        $ret = self::update($data, ['user_id' => $user_id]);
        if (!$ret) {
            RedisCache::del($key);
        }
        if ($ret && isset($data['username'])) {
           // RedisCache::zDelete($listKey, $data['username']);
        }
        return $ret;
    }

    public static function saveMiniProgramDecryptedData($decrypted_data, $user_id)
    {

        $user_info = self::getUserInfoById($user_id);

        Log4dd::info('更新小程序信息到用户信息', ['user_id' => $user_id, 'user_info' => $user_info, 'decrypted_data' => $decrypted_data]);
        if (empty($user_info)) {
            return false;
        }

        $data = [];

        if (empty($user_info['nick_name'])) {
            $data['nick_name'] = $decrypted_data['nickName'] ?? '';
        }

        if (empty($user_info['gender'])) {
            $data['gender'] = $decrypted_data['gender'] ?? '';
        }

        if (empty($user_info['small_avatar_url'])) {
            $data['small_avatar_url'] = $decrypted_data['avatarUrl'] ?? '';
        }

        if (empty($user_info['big_avatar_url'])) {
            $data['big_avatar_url'] = $decrypted_data['avatarUrl'] ?? '';
        }

        if (empty($user_info['country'])) {
            $data['country'] = $decrypted_data['country'] ?? '';
        }

        if (empty($user_info['province'])) {
            $data['province'] = $decrypted_data['province'] ?? '';
        }

        if (empty($user_info['city'])) {
            $data['city'] = $decrypted_data['city'] ?? '';
        }

        if ($data) {
            return self::setUserInfoById($user_id, $data);
        }

        return false;

    }

    public static function getUserPublicInfo($user_id)
    {
        $user_info = self::getUserInfoById($user_id);

        unset($user_info['longitude'], $user_info['latitude'], $user_info['location_hash'],
            $user_info['register_mobile'], $user_info['register_client_id'], $user_info['register_ip'], $user_info['register_version'],
            $user_info['register_time'], $user_info['first_login_time'], $user_info['last_login_client_id'], $user_info['last_login_time'],
            $user_info['last_login_ip'], $user_info['last_login_version'], $user_info['last_update_time']);

        $wish_coin_num = UserAccount::getWishCoinNumByUserId($user_id);

        $user_info['wish_coin_num'] = $wish_coin_num;

        return $user_info;
    }


    /**************************************************admin部分*************************************************/
    /**
     * Desc: 获取用户列表
     * Date: 2020/2/10 20:49
     * Author: yiyu
     * @param array $where
     * @param int $page
     * @param int $page_size
     * @param array $order
     * @return array
     */
    public static function adminGetUserList($where = [], $page = 1, $page_size = 10, $order = [])
    {

        $field = 'user.user_id,user.nick_name,user.gender,user.small_avatar_url,user.register_time,
        user_s.refer_people_num,user_s.initiate_num,user_s.success_num,user_s.pay_num,user_s.pay_money_total,
        user_a.wish_coin_num';
        $query = self::alias('user')
            ->field($field)
            ->join('xy_user_statistics_info user_s', 'user.user_id=user_s.user_id', 'LEFT')
            ->join('xy_user_account user_a', 'user.user_id=user_a.user_id', 'LEFT');

        if ($where) {
            $query->where($where);
        }

        $query->order('user.register_time', 'desc');

        if ($order) {
            $query->order($order);
        }


        $items = $query->paginate($page_size)->toArray();

        return $items;

    }

    public static function adminGetRobotList()
    {
        return self::field('user_id,nick_name,gender,small_avatar_url,register_time')->where('account_type',
            self::ACCOUNT_TYPE_ROBOT)->select();
    }

}